#include "soaEnginerringModel.h"

#include "data_cache.h"

#include "Basc_DCEngineeringModel.pb.h"
#include "calibration_file.h"
#include "eventloop.h"
#include "event_reupload.h"

using namespace DcAdr;

SoaEnginerringModel::SoaEnginerringModel()
{

}

SoaEnginerringModel::~SoaEnginerringModel()
{

}

SoaEnginerringModel &SoaEnginerringModel::getInstance()
{
    static SoaEnginerringModel info;
    return info;
}

//adr-Soa.PB_Basc_DCEngineeringModel_Cnr_StopTask_In
void SoaEnginerringModel::Cnr_StopTask(const std::string &topic, const std::string &requestData, std::string &replyData)
{
    Log_Info("[SoaEnginerringModel][Cnr_StopTask] trigger");

    Soa::PB_Basc_DCEngineeringModel_Cnr_StopTask_In engModel;
    if (!engModel.ParsePartialFromString(requestData))
    {
        Log_ERROR("[SoaEnginerringModel][Cnr_StopTask] parse proto data failed , topic: {}", topic);
    }

    Soa::PB_DC_FileList_Struct fileList = engModel.filelist();

    TriggerEventInfo trigger;
    for (int i = 0; i < fileList.seq_size(); i++)
    {
        TrigerFile trFile;
        trFile.controllerCode = "EDC";
        trFile.fileName = std::string(fileList.seq(i).filepath());
        trigger.otherSysFile.push_back(trFile);
        Log_Info("[SoaEnginerringModel][Cnr_StopTask] trigger path: {}  name: {}", fileList.seq(i).filepath(), fileList.seq(i).filename());
    }

    trigger.triggerTime = DcAdr::Util::getMsTime();
    trigger.recordTime = CommonOprTime::getTime();
    trigger.eventName = "FC001";
    // FC001的采集规则参照BA015
    trigger.beforeTime = 15000.0; //前15s
    trigger.laterTime = 5000.0;   //后5s
    trigger.triggerStartTime =KTime::getPubTime();
    trigger.collectDatas = global_data::g_topics;
    DataCache::getInstance().acquireDataToSave(trigger);

    Soa::PB_Basc_DCEngineeringModel_Cnr_StopTask_Out engModelOut;

    engModelOut.set_return_(0);
    engModelOut.SerializePartialToString(&replyData);

}

//adr-Soa.PB_Basc_DCEngineeringModel_RR_SyncCalibrationFile_In
void SoaEnginerringModel::RR_SyncCalibrationFile(const std::string &topic, const std::string &requestData, std::string &replyData)
{
    Log_Info("[SoaEnginerringModel][RR_SyncCalibrationFile] trigger");
    Soa::PB_Basc_DCEngineeringModel_RR_SyncCalibrationFile_In engModel;
    if (!engModel.ParsePartialFromString(requestData))
    {
        Log_ERROR("[SoaEnginerringModel][RR_SyncCalibrationFile] parse proto data failed , topic: {}", topic);
    }

    std::string vin = engModel.vin();
    std::string tuid = engModel.tuid();

    // 0:成功 1:失败
    Log_Info("[SoaEnginerringModel] [RR_SyncCalibrationFile] trigger, vin = {},  tuid = {} ", vin, tuid);

    auto fun = []()
    {
        uint8_t ret = 0;
        CalibrationFile *file = new CalibrationFile();
        ret = file->init();
        (void)ret;
        delete file;
    };
    appendEvent(ThreadType::E_InFileCacehThread, fun);

    Soa::PB_Basc_DCEngineeringModel_RR_SyncCalibrationFile_Out engModelOut;

    engModelOut.set_return_(0);
    engModelOut.SerializePartialToString(&replyData);

}

uint8_t SoaEnginerringModel::getCalibrationFile()
{
    uint64_t recordTime = CommonOprTime::getTime();
    calibrationFileTime = CommonOprTime::getDateUTC8str(recordTime);

    const string rootPath = global_data::g_tar_calibration_file_path;
    fileName = global_data::g_calibration_prefix + '_' + calibrationFileTime + '.' + global_data::g_calibration_suffix;
    Log_Info("[EnginerringModel] [getCalibrationFile] fileName = {}", fileName);
    filePath = global_data::g_calibration_root_path + fileName;

    const string fc_calib_path = rootPath + "side_calib/";
    const string ldr_calib_path = rootPath + "lidar_calib/";
    const string sc_calib_path = rootPath + "surr_calib/";

    const string find_fc_file = " `find " + fc_calib_path + " -type f -name '*.json' -o -name '*.yaml'` ";
    const string find_ldr_file = " `find " + ldr_calib_path + " -type f -name '*.dat' -o -name '*.yaml'` ";
    const string find_sc_file = " `find " + sc_calib_path + " -type f -name '*.json' -o -name '*.txt' -o -name '*.yaml'` ";

    constexpr const char kCmdPrefix[] = "tar -czf ";
    std::string cmd;
    cmd += kCmdPrefix;

    cmd += filePath;

    cmd += " -P ";

    if (0 == access(fc_calib_path.c_str(), F_OK))
    {
        cmd += " -C ";
        cmd += fc_calib_path;
        cmd += find_fc_file;
    }

    if (0 == access(ldr_calib_path.c_str(), F_OK))
    {
        cmd += " -C ";
        cmd += ldr_calib_path;
        cmd += find_ldr_file;
    }

    if (0 == access(sc_calib_path.c_str(), F_OK))
    {
        cmd += " -C ";
        cmd += sc_calib_path;
        cmd += find_sc_file;
    }

    //调试日志输出
    //tar -czf /ds/ca_adas/ca_adas_20240628143219.tar.gz -P  -C /data/ca_adas/sc_calib/ `find /data/ca_adas/sc_calib/ -type f -name '*.json' -o -name '*.txt'`
    Log_Info("[EnginerringModel][getCalibrationFilecmd] cmd = {}",cmd);
    return (0 == std::system(cmd.c_str()));
}

void SoaEnginerringModel::calibrationFileUpload()
{
    Json::Value root;
    Json::Value header;
    Json::Value param;
    Json::Value data;

    //得到请求ID
    std::string reqId = "";
    CommonOprServser::getReqID(reqId);

    header["v"] = Json::Value("1.0.0");
    header["r"] = Json::Value(reqId);
    header["sk"] = Json::Value("Et_CarData");
    header["m"] = Json::Value("Et_EventFile"); 
    header["a"] = Json::Value(1);
    header["e"] = Json::Value(0);

    param["ec"] = Json::Value("FC011");
    uint64_t time = CommonOprTime::getTime();
    param["ut"] = time;
    param["ts"] = time;
    param["ep"] = "1";
    param["Lng"] = global_data::g_car_location_lng;
    param["Lat"] = global_data::g_car_location_lat;

    Json::Value fileArray;

    Json::Value fileJson;
    fileJson["controllerCode"] = global_data::g_controler_code;
    fileJson["fileName"] = fileName;
    fileJson["filePath"] = filePath;
    fileArray.append(fileJson);

    param["fileCtx"] = fileArray;
    data["p"] = param;
    root["h"] = header;
    root["d"] = data;

    std::string sendStr = root.toStyledString();
    DataBuild::mqttsend(sendStr);

    EventReupload::getInstance().writeJsonString(sendStr);
}